package main.java.com.healthy.dao.impl;

import main.java.com.healthy.dao.HealthAdviceDAO;
import main.java.com.healthy.entity.HealthAdvice;
import main.java.com.healthy.util.FileUtil;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 健康建议数据访问实现类
 */
public class HealthAdviceDAOImpl implements HealthAdviceDAO {

    private static final String ADVICE_DIR = "data/health_advices/";
    private static final String ADVICE_FILE_PREFIX = "advices_";

    // 内存缓存
    private Map<String, List<HealthAdvice>> userAdvicesCache = new HashMap<>();

    public HealthAdviceDAOImpl() {
        // 按需加载
    }

    @Override
    public boolean addAdvice(HealthAdvice advice) {
        try {
            String userId = advice.getUserId();
            List<HealthAdvice> advices = getUserAdvices(userId);

            // 生成唯一建议ID
            if (advice.getAdviceId() == null || advice.getAdviceId().isEmpty()) {
                advice.setAdviceId(generateAdviceId());
            }

            advices.add(advice);
            return saveUserAdvices(userId, advices);
        } catch (Exception e) {
            System.err.println("添加健康建议失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean updateAdvice(HealthAdvice advice) {
        try {
            String userId = advice.getUserId();
            List<HealthAdvice> advices = getUserAdvices(userId);

            for (int i = 0; i < advices.size(); i++) {
                if (advices.get(i).getAdviceId().equals(advice.getAdviceId())) {
                    advices.set(i, advice);
                    return saveUserAdvices(userId, advices);
                }
            }
            return false;
        } catch (Exception e) {
            System.err.println("更新健康建议失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean deleteAdvice(String adviceId) {
        try {
            // 在缓存中查找并删除
            for (String userId : userAdvicesCache.keySet()) {
                List<HealthAdvice> advices = userAdvicesCache.get(userId);
                boolean removed = advices.removeIf(advice -> advice.getAdviceId().equals(adviceId));
                if (removed) {
                    return saveUserAdvices(userId, advices);
                }
            }
            return false;
        } catch (Exception e) {
            System.err.println("删除健康建议失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public HealthAdvice getAdviceById(String adviceId) {
        for (List<HealthAdvice> advices : userAdvicesCache.values()) {
            for (HealthAdvice advice : advices) {
                if (advice.getAdviceId().equals(adviceId)) {
                    return advice;
                }
            }
        }
        return null;
    }

    @Override
    public List<HealthAdvice> getAdvicesByUserId(String userId) {
        List<HealthAdvice> advices = getUserAdvices(userId);
        return advices.stream()
                .sorted((a1, a2) -> {
                    // 按优先级和生成日期排序
                    int priorityCompare = Integer.compare(a1.getPriorityCode(), a2.getPriorityCode());
                    if (priorityCompare != 0) {
                        return priorityCompare;
                    }
                    return a2.getGenerateDate().compareTo(a1.getGenerateDate());
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<HealthAdvice> getUnreadAdvicesByUserId(String userId) {
        List<HealthAdvice> advices = getUserAdvices(userId);
        return advices.stream()
                .filter(advice -> !advice.isRead())
                .sorted((a1, a2) -> Integer.compare(a1.getPriorityCode(), a2.getPriorityCode()))
                .collect(Collectors.toList());
    }

    @Override
    public List<HealthAdvice> getAdvicesByType(String userId, String adviceType) {
        List<HealthAdvice> advices = getUserAdvices(userId);
        return advices.stream()
                .filter(advice -> advice.getAdviceType().equals(adviceType))
                .collect(Collectors.toList());
    }

    @Override
    public boolean markAsRead(String adviceId) {
        try {
            HealthAdvice advice = getAdviceById(adviceId);
            if (advice != null) {
                advice.setRead(true);
                return updateAdvice(advice);
            }
            return false;
        } catch (Exception e) {
            System.err.println("标记建议为已读失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean markAsImplemented(String adviceId) {
        try {
            HealthAdvice advice = getAdviceById(adviceId);
            if (advice != null) {
                advice.setImplemented(true);
                return updateAdvice(advice);
            }
            return false;
        } catch (Exception e) {
            System.err.println("标记建议为已实施失败: " + e.getMessage());
            return false;
        }
    }

    @Override
    public List<HealthAdvice> getHighPriorityAdvices(String userId) {
        List<HealthAdvice> advices = getUserAdvices(userId);
        return advices.stream()
                .filter(advice -> "高".equals(advice.getPriority()))
                .collect(Collectors.toList());
    }

    @Override
    public boolean deleteExpiredAdvices(String userId) {
        try {
            List<HealthAdvice> advices = getUserAdvices(userId);
            LocalDate expiryDate = LocalDate.now().minusDays(30);

            boolean removed = advices.removeIf(advice ->
                    advice.getGenerateDate().isBefore(expiryDate) && advice.isRead());

            if (removed) {
                return saveUserAdvices(userId, advices);
            }
            return true; // 没有过期建议也算成功
        } catch (Exception e) {
            System.err.println("删除过期建议失败: " + e.getMessage());
            return false;
        }
    }

    /**
     * 生成唯一建议ID
     */
    private String generateAdviceId() {
        return "ADVICE_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }

    /**
     * 获取用户的健康建议
     */
    @SuppressWarnings("unchecked")
    private List<HealthAdvice> getUserAdvices(String userId) {
        if (userAdvicesCache.containsKey(userId)) {
            return userAdvicesCache.get(userId);
        }

        String filename = ADVICE_DIR + ADVICE_FILE_PREFIX + userId + ".dat";
        try {
            Object data = FileUtil.readObject(filename);
            if (data instanceof List) {
                List<HealthAdvice> advices = (List<HealthAdvice>) data;
                userAdvicesCache.put(userId, advices);
                return advices;
            } else {
                List<HealthAdvice> advices = new ArrayList<>();
                userAdvicesCache.put(userId, advices);
                return advices;
            }
        } catch (Exception e) {
            System.err.println("加载健康建议失败: " + e.getMessage());
            List<HealthAdvice> advices = new ArrayList<>();
            userAdvicesCache.put(userId, advices);
            return advices;
        }
    }

    /**
     * 保存用户的健康建议
     */
    private boolean saveUserAdvices(String userId, List<HealthAdvice> advices) {
        String filename = ADVICE_DIR + ADVICE_FILE_PREFIX + userId + ".dat";
        try {
            userAdvicesCache.put(userId, advices);
            return FileUtil.writeObject(filename, advices);
        } catch (Exception e) {
            System.err.println("保存健康建议失败: " + e.getMessage());
            return false;
        }
    }
}